package org.stvd.service.common.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.stvd.common.SecurityUserHolder;
import org.stvd.common.enums.UserLoginTypeEnum;
import org.stvd.common.enums.VerifyCodeTypeEnum;
import org.stvd.common.utils.SMSUtil;
import org.stvd.common.utils.ServiceResult;
import org.stvd.common.utils.ServiceUtils;
import org.stvd.common.utils.VerifyUtil;
import org.stvd.core.util.DateUtil;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.admin.Params;
import org.stvd.entities.admin.UserLogin;
import org.stvd.entities.common.MsgSendHis;
import org.stvd.entities.common.VerifyTmp;
import org.stvd.entities.common.VerifyTmpPK;
import org.stvd.repository.admin.ParamsDao;
import org.stvd.repository.admin.UserLoginDao;
import org.stvd.repository.admin.UsersDao;
import org.stvd.repository.common.MsgSendHisDao;
import org.stvd.repository.common.VerifyTmpDao;
import org.stvd.service.base.impl.BaseServiceImpl;
import org.stvd.service.common.MsgSendHisService;

@Service("msgSendHisService")
public class MsgSendHisServiceImpl extends BaseServiceImpl<MsgSendHis> implements MsgSendHisService {

    @Resource(name = "MsgSendHisDao")
    private MsgSendHisDao msgSendHisDao;
    @Resource(name = "UserLoginDao")
    private UserLoginDao userLoginDao;
    @Resource(name = "UsersDao")
    private UsersDao usersDao;
    @Resource(name = "ParamsDao")
    private ParamsDao paramsDao;
    @Resource(name = "VerifyTmpDao")
    private VerifyTmpDao verifyTmpDao;
    @Resource(name = "VerifyTmpDao")
    private VerifyTmpDao verifyTmpao;

    @Override
    public int countSendTimesTheDay(String dateStr, String receiverNum, String useFor) {
        return msgSendHisDao.countSendTimesTheDay(dateStr, receiverNum, useFor);
    }

    @Override
    public ServiceResult<Map<String, Object>> sendMobileMsg(String signName, String moblieNumStr, String templateCode,
        Map<String, String> templateParamMap, String msgUseFor, String msgSendPerson, String msgContent) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<>();
        if(StringUtil.isEmpty(moblieNumStr)) {
            serviceResult.setParamError("手机号不能为空");
            return serviceResult;
        }
        if(!VerifyUtil.isMobile(moblieNumStr)) {
            serviceResult.setParamError("手机号格式有误");
            return serviceResult;
        }
        Map<String, String> sendResult = SMSUtil.sendMessageByAliYun(signName, new Long(moblieNumStr), templateCode, templateParamMap);
        if (sendResult == null) {
            serviceResult.setDataError("发送失败，请重试！");
            return serviceResult;
        }
        //保存短信发送记录
        MsgSendHis msgSendHis = new MsgSendHis();
        msgSendHis.setHisId(StringUtil.getRandomUUID());
        msgSendHis.setUseFor(StringUtil.isEmpty(msgUseFor) ? "短信业务通知" :msgUseFor);
        msgSendHis.setReceiverNo(moblieNumStr);
        msgSendHis.setSendPerson(msgSendPerson);
        msgSendHis.setContent(msgContent);
        msgSendHis.setSendTime(DateUtil.getSystemDate());
        this.insert(msgSendHis);
        
        serviceResult.setMessage("短信发送成功");
        return serviceResult;
    }
    
    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> sendAndRegisterMobileCode(String moblieNumStr, String guid) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<>();
        if(StringUtil.isEmpty(moblieNumStr)) {
            serviceResult.setParamError("手机号不能为空");
            return serviceResult;
        }
        if(!VerifyUtil.isMobile(moblieNumStr)) {
            serviceResult.setParamError("手机号格式有误");
            return serviceResult;
        }
        UserLogin userLogin = userLoginDao.findUserLoginByLoginAccount(moblieNumStr);
        if(userLogin!=null) {
            serviceResult.setParamError("当前手机号已注册，请更换手机号");
            return serviceResult;
        }
        VerifyTmp verifyTemp = verifyTmpao
                .findByPK(new VerifyTmpPK(moblieNumStr, VerifyCodeTypeEnum.Regist.getValue()));
        if (verifyTemp!=null && ((DateUtil.getSystemDate().getTime()
                - verifyTemp.getInputDatetime().getTime()) < (1000*60))) {
            serviceResult.setDataError("获取验证码过于频繁，请稍等片刻！");
            return serviceResult;
        }
        int sendCount = countSendTimesTheDay(DateUtil.getSystemDateString(), moblieNumStr, VerifyCodeTypeEnum.Regist.getValue());
        if(sendCount >= 5) {
            serviceResult.setDataError("当前手机号获取验证码次数已超出本日最大限制！");
            return serviceResult;
        }
        String vCode = ServiceUtils.getRandomCode(6, "2"); // 6位纯数字验证码
        String msgSignName = "";
        List<Params> paramsList = paramsDao.findByParamName(guid, "MSG_SIGN_NAME");
        if(paramsList!=null && paramsList.size() > 0) {
            msgSignName = paramsList.get(0).getParamValue();
        }
        String msgTemplateName = "";
        paramsList = paramsDao.findByParamName(guid, "MSG_REGIST_TEMPLATE");
        if(paramsList!=null && paramsList.size() > 0) {
            msgTemplateName = paramsList.get(0).getParamValue();
        }
        @SuppressWarnings("serial")
        Map<String, String> sendResult = SMSUtil.sendMessageByAliYun(msgSignName, new Long(moblieNumStr), msgTemplateName,
            new HashMap<String, String>(1) {
                {
                    put("code", vCode);
                }
            }
        );
        if (sendResult.containsKey("errorMsg")) {
            serviceResult.setDataError(sendResult.get("errorMsg"));
            return serviceResult;
        }
        Date nowTime = DateUtil.getSystemDate();
        //保存短信发送记录
        MsgSendHis msgSendHis = new MsgSendHis();
        msgSendHis.setHisId(StringUtil.getRandomUUID());
        msgSendHis.setUseFor(VerifyCodeTypeEnum.Regist.getText());
        msgSendHis.setReceiverNo(moblieNumStr);
        msgSendHis.setContent("账号注册验证码："+vCode);
        msgSendHis.setSendTime(nowTime);
        this.insert(msgSendHis);
        //保存验证码
        verifyTmpDao.update(
                new VerifyTmp(moblieNumStr, VerifyCodeTypeEnum.Regist.getValue(), vCode, nowTime));
        serviceResult.setMessage("发送成功");
        return serviceResult;
        
    }

    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> sendAndBindingMobileCode(String moblieNumStr, String guid) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<>();
        if(StringUtil.isEmpty(moblieNumStr)) {
            serviceResult.setParamError("手机号不能为空");
            return serviceResult;
        }
        if(!VerifyUtil.isMobile(moblieNumStr)) {
            serviceResult.setParamError("手机号格式有误");
            return serviceResult;
        }
        UserLogin userLogin = userLoginDao.findUserLoginByLoginAccount(moblieNumStr);
        if(userLogin!=null) {
            serviceResult.setParamError("当前手机号已绑定账号，请更换手机号");
            return serviceResult;
        }
        VerifyTmp verifyTemp = verifyTmpao
                .findByPK(new VerifyTmpPK(moblieNumStr, VerifyCodeTypeEnum.Bind.getValue()));
        if (verifyTemp!=null && ((DateUtil.getSystemDate().getTime()
                - verifyTemp.getInputDatetime().getTime()) < (1000*60))) {
            serviceResult.setDataError("获取验证码过于频繁，请稍等片刻！");
            return serviceResult;
        }
        int sendCount = countSendTimesTheDay(DateUtil.getSystemDateString(), moblieNumStr, VerifyCodeTypeEnum.Bind.getValue());
        if(sendCount >= 5) {
            serviceResult.setDataError("当前手机号获取验证码次数已超出本日最大限制！");
            return serviceResult;
        }
        String vCode = ServiceUtils.getRandomCode(6, "2"); // 6位纯数字验证码
        String msgSignName = "";
        List<Params> paramsList = paramsDao.findByParamName(guid, "MSG_SIGN_NAME");
        if(paramsList!=null && paramsList.size() > 0) {
            msgSignName = paramsList.get(0).getParamValue();
        }
        String msgTemplateName = "";
        paramsList = paramsDao.findByParamName(guid, "MSG_CHANGE_TEMPLATE");
        if(paramsList!=null && paramsList.size() > 0) {
            msgTemplateName = paramsList.get(0).getParamValue();
        }
        @SuppressWarnings("serial")
        Map<String, String> sendResult = SMSUtil.sendMessageByAliYun(msgSignName, new Long(moblieNumStr), msgTemplateName,
                new HashMap<String, String>(1) {
                    {
                        put("code", vCode);
                    }
                }
        );
        if (sendResult.containsKey("errorMsg")) {
            serviceResult.setDataError(sendResult.get("errorMsg"));
            return serviceResult;
        }
        Date nowTime = DateUtil.getSystemDate();
        //保存短信发送记录
        MsgSendHis msgSendHis = new MsgSendHis();
        msgSendHis.setHisId(StringUtil.getRandomUUID());
        msgSendHis.setUseFor(VerifyCodeTypeEnum.Bind.getText());
        msgSendHis.setReceiverNo(moblieNumStr);
        msgSendHis.setContent("手机绑定验证码："+vCode);
        msgSendHis.setSendPerson(SecurityUserHolder.getCurrentUserid());
        msgSendHis.setSendTime(nowTime);
        this.insert(msgSendHis);

        //保存验证码
        verifyTmpDao.update(
                new VerifyTmp(moblieNumStr, VerifyCodeTypeEnum.Bind.getValue(), vCode, nowTime));
        serviceResult.setMessage("发送成功");
        return serviceResult;
    }


    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> sendAndResetPasswordMobileCode(String moblieNumStr, String guid) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<>();
        if(StringUtil.isEmpty(moblieNumStr)) {
            serviceResult.setParamError("手机号不能为空");
            return serviceResult;
        }
        if(!VerifyUtil.isMobile(moblieNumStr)) {
            serviceResult.setParamError("手机号格式有误");
            return serviceResult;
        }
        UserLogin userLogin = userLoginDao.findUserLoginByTypeAccount(UserLoginTypeEnum.Mobile.getValue(), moblieNumStr);
        if(userLogin==null) {
            serviceResult.setDataError("当前手机号尚未绑定，不能用于重置密码操作");
            return serviceResult;
        }
         VerifyTmp verifyTemp = verifyTmpao
                .findByPK(new VerifyTmpPK(moblieNumStr, VerifyCodeTypeEnum.ResetPassword.getValue()));
        if (verifyTemp!=null && ((DateUtil.getSystemDate().getTime()
                - verifyTemp.getInputDatetime().getTime()) < (1000*60))) {
            serviceResult.setDataError("获取验证码过于频繁，请稍等片刻！");
            return serviceResult;
        }
        int sendCount = countSendTimesTheDay(DateUtil.getSystemDateString(), moblieNumStr, VerifyCodeTypeEnum.ResetPassword.getValue());
        if(sendCount >= 5) {
            serviceResult.setDataError("当前手机号获取验证码次数已超出本日最大限制！");
            return serviceResult;
        }
        String vCode = ServiceUtils.getRandomCode(6, "2"); // 6位纯数字验证码
        String msgSignName = "";
        List<Params> paramsList = paramsDao.findByParamName(guid, "MSG_SIGN_NAME");
        if(paramsList!=null && paramsList.size() > 0) {
            msgSignName = paramsList.get(0).getParamValue();
        }
        String msgTemplateName = "";
        paramsList = paramsDao.findByParamName(guid, "MSG_RESET_TEMPLATE");
        if(paramsList!=null && paramsList.size() > 0) {
            msgTemplateName = paramsList.get(0).getParamValue();
        }
        @SuppressWarnings("serial")
        Map<String, String> sendResult = SMSUtil.sendMessageByAliYun(msgSignName, new Long(moblieNumStr), msgTemplateName,
                new HashMap<String, String>(1) {
                    {
                        put("code", vCode);
                    }
                }
        );
        if (sendResult.containsKey("errorMsg")) {
            serviceResult.setDataError(sendResult.get("errorMsg"));
            return serviceResult;
        }
        Date nowTime = DateUtil.getSystemDate();
        //保存短信发送记录
        MsgSendHis msgSendHis = new MsgSendHis();
        msgSendHis.setHisId(StringUtil.getRandomUUID());
        msgSendHis.setUseFor(VerifyCodeTypeEnum.ResetPassword.getText());
        msgSendHis.setReceiverNo(moblieNumStr);
        msgSendHis.setContent("找回密码验证码："+vCode);
        msgSendHis.setSendTime(nowTime);
        this.insert(msgSendHis);

        //保存验证码
        verifyTmpDao.update(
                new VerifyTmp(moblieNumStr, VerifyCodeTypeEnum.ResetPassword.getValue(), vCode, nowTime));
        serviceResult.setMessage("发送成功");
        return serviceResult;
    }

    @Override
    @Transactional
    public ServiceResult<Map<String, Object>> sendAndAuthorizationMobileCode(String moblieNumStr, String guid) {
        ServiceResult<Map<String, Object>> serviceResult = new ServiceResult<>();
        if(StringUtil.isEmpty(moblieNumStr)) {
            serviceResult.setParamError("手机号不能为空");
            return serviceResult;
        }
        if(!VerifyUtil.isMobile(moblieNumStr)) {
            serviceResult.setParamError("手机号格式有误");
            return serviceResult;
        }
        UserLogin userLogin = userLoginDao.findUserLoginByTypeAccount(UserLoginTypeEnum.Mobile.getValue(), moblieNumStr);
        if(userLogin==null) {
            serviceResult.setDataError("当前手机号尚未注册！");
            return serviceResult;
        }
         VerifyTmp verifyTemp = verifyTmpao
                .findByPK(new VerifyTmpPK(moblieNumStr, VerifyCodeTypeEnum.Authorization.getValue()));
        if (verifyTemp!=null && ((DateUtil.getSystemDate().getTime()
                - verifyTemp.getInputDatetime().getTime()) < (1000*60))) {
            serviceResult.setDataError("获取验证码过于频繁，请稍等片刻！");
            return serviceResult;
        }
        int sendCount = countSendTimesTheDay(DateUtil.getSystemDateString(), moblieNumStr, VerifyCodeTypeEnum.Authorization.getValue());
        if(sendCount >= 5) {
            serviceResult.setDataError("当前手机号获取验证码次数已超出本日最大限制！");
            return serviceResult;
        }
        String vCode = ServiceUtils.getRandomCode(6, "2"); // 6位纯数字验证码
        String msgSignName = "";
        List<Params> paramsList = paramsDao.findByParamName(guid, "MSG_SIGN_NAME");
        if(paramsList!=null && paramsList.size() > 0) {
            msgSignName = paramsList.get(0).getParamValue();
        }
        String msgTemplateName = "";
        paramsList = paramsDao.findByParamName(guid, "MSG_AUTH_TEMPLATE");
        if(paramsList!=null && paramsList.size() > 0) {
            msgTemplateName = paramsList.get(0).getParamValue();
        }
        @SuppressWarnings("serial")
        Map<String, String> sendResult = SMSUtil.sendMessageByAliYun(msgSignName, new Long(moblieNumStr), msgTemplateName,
                new HashMap<String, String>(1) {
                    {
                        put("code", vCode);
                    }
                }
        );
        if (sendResult.containsKey("errorMsg")) {
            serviceResult.setDataError(sendResult.get("errorMsg"));
            return serviceResult;
        }
        Date nowTime = DateUtil.getSystemDate();
        //保存短信发送记录
        MsgSendHis msgSendHis = new MsgSendHis();
        msgSendHis.setHisId(StringUtil.getRandomUUID());
        msgSendHis.setUseFor(VerifyCodeTypeEnum.Authorization.getText());
        msgSendHis.setReceiverNo(moblieNumStr);
        msgSendHis.setContent("用户授权验证码："+vCode);
        msgSendHis.setSendTime(nowTime);
        this.insert(msgSendHis);

        //保存验证码
        verifyTmpDao.update(
                new VerifyTmp(moblieNumStr, VerifyCodeTypeEnum.Authorization.getValue(), vCode, nowTime));
        serviceResult.setMessage("发送成功");
        return serviceResult;
    }
}
